Skip to content

feat(tests): allow RUST_LOG with multiple tags for native executables#2452

Draft
dimxy wants to merge 9 commits intodevfrom
allow-rust-log-tags
Draft

feat(tests): allow RUST_LOG with multiple tags for native executables#2452
dimxy wants to merge 9 commits intodevfrom
allow-rust-log-tags

Conversation

@dimxy
Copy link
Collaborator

@dimxy dimxy commented May 12, 2025

This PR removes unneeded RUST_LOG parsing for test mm2 startup code, native platform, in the test_mm_start fn (it failed when RUST_LOG had multiple tags). This code change allows to use arbitrary RUST_LOG, with multiple tags (like RUST_LOG=off or RUST_LOG="debug,libp2p_gossipsub=info,rustls=error,mm2_main::database=error,mm2_p2p=info,multistream_select=error") for native mm2 executable in docker and other tests.

The fix ensures the p2p module has info log level (needed for wait_for_log fn, used in tests).
The fix also refactors the check_seednodes test fn: instead of waiting for Completed IAmrelay debug message (not available if debug=off) it queries get_directly_connected_peers RPC to ensure a remote peer is connected.

This PR should be useful to hide unneeded debug logs, while developing tests running mm2 executables.
(Please note that some tests in docker_ordermatch_tests or tendermint_tests modules still need libp2p DEBUG logs.)

…ests, ensure info level for p2p for wait_for_log to work
Copy link

@borngraced borngraced left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, minor suggestions.

.env("RUST_LOG", "debug")
.envs(envs.to_vec())
.env("RUST_LOG", read_rust_log().as_str())
.envs(envs_fixed.iter().map(|(k, v)| (k, v)))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.envs(envs_fixed.iter().map(|(k, v)| (k, v)))
.envs(envs_fixed.iter()))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

borngraced
borngraced previously approved these changes May 12, 2025
Comment on lines 29 to 33
let filter = if let Ok(log_var) = var("RUST_LOG") {
LogLevel::from_str(&log_var).ok(); // Actually filter is used for wasm only. For native RUST_LOG is parsed by env_logger directly, allowing setting multiple targets
} else {
None
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let filter = if let Ok(log_var) = var("RUST_LOG") {
LogLevel::from_str(&log_var).ok(); // Actually filter is used for wasm only. For native RUST_LOG is parsed by env_logger directly, allowing setting multiple targets
} else {
None
};
// Actually filter is used for wasm only. For native RUST_LOG is parsed by env_logger directly, allowing setting multiple targets
let filter = var("RUST_LOG").map(|l| LogLevel::from_str(&log_var).ok());

@dimxy
Copy link
Collaborator Author

dimxy commented May 12, 2025

I suggest removing log dumps inside run_taker_node run_maker_node run_watcher_node in swap_watcher_tests.rs: (864e7e5).
They dump incomplete logs (before tests calling them finish), so in fact misleading.
Instead we should create log dumps in test functions, if needed.

Comment on lines 1384 to 1385
.env("RUST_LOG", read_rust_log().as_str())
.envs(envs_fixed.iter().map(|(k, v)| (k, v)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the rust_log was set, we would have two rust_logs set for the child process here. one from .env("RUST_LOG",...) and another from .envs(envs_fixed...). is this OK? can't we rely on our own only one of them, say the former.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's okay as envs fn according to the doc 'Inserts or updates multiple explicit environment variable mappings.'

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ummmm, i mean, there is no reason to provide it two times anyways.
if we can make it so fix_rust_log_if_present be remove_rust_log_if_present instead, we won't have repeated RUST_LOGs.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe, the second RUST_LOG var (if present) would overwrite the first one in the inner 'set' of env vars

Comment on lines 16 to 22
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn test_mm_start() { test_mm_start_impl(); }

pub fn test_mm_start_impl() {
#[cfg(not(target_arch = "wasm32"))]
fn test_mm_start_impl() {
if let Ok(conf) = var("_MM2_TEST_CONF") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can merge these 2 funcs. as of now, doesn't seem that this indirection is useful.

Comment on lines 4147 to 4153
.map(|s| {
if s.starts_with(&(module.to_owned() + "=off")) {
module.to_owned() + "=info"
} else {
s.to_owned()
}
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be simplified to

            // If the module is already set to off, remove it.
            .filter(|s| s == &&(module.to_owned() + "=off"))

since we will add module=info later anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only .filter(|s| s != &&(module.to_owned() + "=off"))

Comment on lines -303 to -308
let (_dump_log, _dump_dashboard) = mm.mm_dump();
log!("Log path: {}", mm.log_path.display());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we removing these. and other occurrences too.

Copy link
Collaborator Author

@dimxy dimxy Jul 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing _dump_log inside the run_watcher_node because _dump_log here, when dropped on run_watcher_node exit, dumps incomplete log.
Instead new _watcher_dump_log is added in the test fn itself (so it dumps the log when the test finishes).

);

// check with too big time offset:
let (bob_peers, alice_peers) = start_peers_with_time_offset(timeoffset_too_big);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how did this used to work before even tho the default behavior is setting skip_seednodes_check = false?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It had worked before this PR because the node waited for log message 'Completed IAmrelay handling for peer' and this message always was added to the log when a peer connected (even if the peer was later rejected due to big time diff)

Comment on lines +1692 to +1696
if let Some(ref mut pc) = self.pc {
if !pc.running() {
return ERR!("MM process terminated prematurely at: {:?}.", self.folder);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't understand why we had this, but looks like it's some logic found in wait_for_log that was used before.

i think the fact that the rpc replied to us is enough to determine that mm2 is alive, so such a check isn't really needed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd better catch the error from self.rpc() so we can progress and stop with the known "MM process terminated prematurely" error

Comment on lines 1675 to 1678
let res = self.rpc(&json!({
"userpass": self.userpass,
"method": "get_directly_connected_peers",
}))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess that's a different check than what the funciton name tells, ha?

this queries connected peers, but in this function we wanna check connected seeds.
not sure if the old implementation used to check for seeds and not any peer (the log we used to wait for doesn't really point that it was waiting specifically for a seed).

it doesn't matter i think since in all test scenarios we have a seed peer connected to non-seed peer. we might just wanna rename the function to reflect the job it's doing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed,
tyvm for the notes

@shamardy shamardy marked this pull request as draft June 16, 2025 04:59
shamardy and others added 3 commits July 24, 2025 15:41
…eers check, eliminate test_mm_start_impl, use combinator in rust_log parse
* dev:
  fix(DOCS): add note for macos to fix docker containers startup failure (#2544)
  refactor(toolchain): general stabilization for stable rust (#2528)

# Conflicts:
#	mm2src/mm2_main/tests/integration_tests_common/mod.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants